--[[
	有限状态机
--]]
local FSM = require("fsm")
require("functions")

local QFsm = class()


-- FSM CONSTANTS --------------------------------------------------------------
local SEPARATOR = '.'
local ANY       = '*'
local ANYSTATE  = ANY .. SEPARATOR
local ANYEVENT  = SEPARATOR .. ANY
local UNKNOWN   = ANYSTATE .. ANY

function QFsm:ctor(t)
	
	self.state = t[1][1]	-- 第一个设为默认状态
	self.stt = {}			-- 事件表 包含 当前状态-要到的状态-回调
	self.str = ""			-- <self.state><SEPARATOR><event> combination
	self.silence = false	-- 沉默状态不打印错误


	-- initalise self.state transition table
	self.stt[UNKNOWN] = {newState = self.state, action = function(...) QFsm.exception(self) end}
	
	self:add(t)		
end
	
function QFsm:set(s)
	self.state = s 
end

function QFsm:get()
	return self.state	
end

function QFsm:silent()
	self.silence = true 
end

-- default exception handling
function QFsm:exception() 
	if self.silence == false then 
		print("FSM: unknown combination: " .. self.str)
	end
	return false
end	
	
-- respond based on current self.state and event
function QFsm:fire(event)
	local act = self.stt[self.state .. SEPARATOR .. event]
	-- raise exception for unknown state-event combination
	if act == nil then 
		-- search for wildcard "states" for this event
		act = self.stt[ANYSTATE .. event]
		-- if still not a match than check any event
		if act == nil then
			-- check if there is a wildcard event
			act = self.stt[self.state .. ANYEVENT]
			if act == nil then
				act = self.stt[UNKNOWN]; 
				self.str = self.state .. SEPARATOR .. event 
			end
		end
	end
	-- print("_______1111______",act.newState,event)
	-- set next self.state as current self.state
	self.state = act.newState	
	
	return act.action()
end

-- add new self.state transitions to the FSM
function QFsm:add(t)
	for _,v in ipairs(t) do
		local oldState, event, newState, action = v[1], v[2], v[3], v[4]
		self.stt[oldState .. SEPARATOR .. event] = {newState = newState, action = action}
	end
	return #t	-- the requested number of self.state-transitions to be added 
end
	
-- remove self.state transitions from the FSM
function QFsm:delete(t)
	for _,v in ipairs(t) do
		local oldState, event = v[1], v[2]
		if oldState == ANY and event == ANY then
			if not self.silence then
				print( "FSM: you should not delete the exception handler" )
				print( "FSM: but assign another exception action" )
			end 
			-- assign default exception handler but stay in current self.state
			self.stt[exception] = {newState = self.state, action = exception}
		else
			self.stt[oldState .. SEPARATOR .. event] = nil
		end
	end
	return #t 	-- the requested number of self.state-transitions to be deleted
end
	


local Test = class()
function Test:ctor()
	--状态
	--state1 --eventName --state2 --callback
	self.gameStateTransitionTable = {
		{"rest", 		"to_start", 	"start", 		function() self:onStart() end },
		{"start", 		"to_bet",		"bet", 			function() self:onBet() end },
		{"bet", 		"to_open",		"open", 		function() self:onOpen() end },
		{"*", 			"to_global",		"global", 		function() self:onGlobal() end }, 
		{"global", 		"leave_global",		"*", 		function() self:onLeaveGlobal() end },
	}
	--状态机
	self.fsm = QFsm.new(self.gameStateTransitionTable)	
end
function Test:onStart()
	print("______________start__")
end
function Test:onBet()
	print("______________bet__")
end
function Test:onOpen()
	print("______________open__")
end
function Test:onGlobal( ... )
	print("___________global___")
end
function Test:onLeaveGlobal( ... )
	print("__________leave_global___")
end

local test = Test.new()
test.fsm:set("rest")
test.fsm:fire("to_start")
test.fsm:fire("to_bet")
test.fsm:fire("to_open")

-- test.fsm:fire("to_global")
-- print(test.fsm:get())
-- test.fsm:fire("leave_global")
-- print(test.fsm:get())



return QFsm